/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "面/面.h"
#include "数学/数学.h"

#include <file_文件名数据.h>


static std::unordered_map<std::u16string, S_GPU内存块> g矢量图标坐标;
static std::unordered_map<std::u16string, S_GPU内存块> g矢量图标索引;
static std::unordered_map<std::u16string, S_GPU内存块> g矢量图标轮廓;





void f_surface_加载矢量图标(S_设备环境& ctx, std::filesystem::path 路径, std::u16string name) {
	S_目录文件包 包;
	f_file_get目录下所有文件名(路径.string(), 包, ".svg");

	uint32 图标数量 = 包.文件.size();
	std::vector<S_2D路径层>				polygon_2D路径(图标数量);
	std::vector<std::vector<uint32>>	polygon_三角形(图标数量);
	std::vector<std::vector<mat2>>		路径顶点(图标数量);

	for (uint32 i = 0; i < 图标数量; ++i) {
		
		std::filesystem::path path = 路径 / 包.文件[i];
		auto data = f_svg_load(path.generic_string());

		for (auto& e : data.graph) {
			if(e.point.empty()) continue;
			vec2 size = max(data.maxBound - data.minBound, data.bound);

			e.point /= max(size.x, size.y);

			polygon_2D路径[i] = f_polygon_构建2D路径(e.point, e.edges);
			polygon_2D路径[i].inOut = e.path_type;

			if (polygon_2D路径[i].point.size()) {
				polygon_三角形[i] = f_polygon_从链表构建三角形(polygon_2D路径[i]);

				for (auto& e : polygon_2D路径[i].point) {
					路径顶点[i].push_back({e - 0.5f, {1,1}});
				}
			}
			break;
		}
	}


	uint32 坐标起始索引 = 0;
	for (uint32 i = 0; i < 图标数量; ++i) {
		auto key = f_file_get无后缀文件名(包.文件[i]);

		auto 顶点 = f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_顶点, 0);
		auto 索引 = f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_索引, 0);
		auto 轮廓 = f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_索引, 0);

		f_bm_fill(顶点, 路径顶点[i].data(), 路径顶点[i].size());

		uint32 坐标起始索引 = 顶点.m_Mem.m_偏移;
		std::vector<uint32> 轮廓索引;

		for (auto& e : polygon_2D路径[i].index) {
			int32 索引数量 = max(0, int32(e.size()) - 1);

			auto it = e.begin();
			for (uint32 v = 0; v < 索引数量; ++v) {
				轮廓索引.emplace_back(坐标起始索引 + it->p);
				轮廓索引.emplace_back(坐标起始索引 + std::next(it)->p);
				++it;
			}
		}
		
		polygon_三角形[i] += 坐标起始索引;
		f_bm_fill(索引, polygon_三角形[i].data(), polygon_三角形[i].size());
		f_bm_fill(轮廓, 轮廓索引.data(), 轮廓索引.size());

		g矢量图标坐标[key] = 顶点;
		g矢量图标索引[key] = 索引;
		g矢量图标轮廓[key] = 轮廓;
	}
}

void f_surface_卸载矢量图标(S_设备环境& ctx, std::u16string name) {
	for (auto& e : g矢量图标坐标) {
		f_bm_erase(e.second);
	}
	g矢量图标坐标.clear();
}




S_VkDrawIndexedIndirectCommand f_vg_getIco(const std::u16string& name, bool 面) {
	
	S_VkDrawIndexedIndirectCommand indirect;
	indirect.vertexOffset = 0;
	indirect.firstInstance = 0;
	indirect.instanceCount = 1;

	if (面) {
		auto& e = g矢量图标索引[name];

		indirect.firstIndex = e.m_Mem.m_偏移;
		indirect.indexCount = e.m_Mem.m_数量;
	}
	else {
		auto& e = g矢量图标轮廓[name];

		indirect.firstIndex = e.m_Mem.m_偏移;
		indirect.indexCount = e.m_Mem.m_数量;
		
	}
	return indirect;
}

